<script>
    import minxin from "@/utils/mixins"
    import { prefixCls } from '../prefix'
    export default {
        name: `${prefixCls}Dropdown`,

        componentName: `${prefixCls}Dropdown`,

        mixins: [minxin],

        props: {
            trigger: {
                type: String,
                default: 'hover'
            },
            placement: {
                type: String,
                default: 'center'
            },
            transfer: {
                type: Boolean,
                default: true
            },
            transferClassName: {
                type: String,
                default: ''
            }
        },

        data() {
            return {
                visible: false,
                timeout: null
            }
        },

        mounted() {
            this.init() //初始化组件元素
            this.initEvent() //添加组件元素事件
        },

        methods: {
            init() {
                this.buttonEl = this.$slots.default[0].elm; //组件按钮
                this.dropdownEl = this.$slots.dropdown[0].elm; //组件下拉框
                this.dropdownItem = this.dropdownEl.querySelectorAll("li")
            },
            initEvent() {
                let { trigger, buttonEl, dropdownEl, hide, show, handleClick, handleKeyDown, handleMenuKeyDown } = this
                buttonEl.addEventListener("keydown", handleKeyDown); //按钮键盘事件监听
                dropdownEl.addEventListener("keydown", handleMenuKeyDown); //下拉菜单键盘事件监听
                if (trigger === 'hover') {
                    buttonEl.addEventListener('mouseenter', show);
                    buttonEl.addEventListener('mouseleave', hide);
                    dropdownEl.addEventListener('mouseenter', show);
                    dropdownEl.addEventListener('mouseleave', hide);
                } else if (trigger === 'click') {
                    buttonEl.addEventListener("click", handleClick); //按钮点击设置显示隐藏
                }
                document.addEventListener("click", event => {
                    if (!buttonEl.contains(event.target) && this.visible) {
                        hide()
                    }
                }) //点击整个窗口下拉框消失
                this.$on("menu-item-click", this.handleMenuItemClick) //注册下拉菜单点击事件
            },
            handleClick() {
                this.visible ? this.hide() : this.show()
            },
            handleKeyDown(event) {
                let keyCode = event.keyCode
                if (keyCode == 38 || keyCode == 40) {
                    // up|down
                    this.resetIndex(0)
                    this.dropdownItem[0].focus()
                    event.preventDefault()
                    event.stopPropagation()
                }
                return;
            },
            handleMenuKeyDown(event) {
                let keyCode = event.keyCode
                let currentIndex = [].indexOf.call(this.dropdownItem, event.target)
                let max = this.dropdownItem.length - 1
                let nextIndex

                if (keyCode == 38 || keyCode == 40) {
                    // up|down
                    if (keyCode === 38) {
                        // up
                        nextIndex = currentIndex !== 0 ? currentIndex - 1 : 0
                    } else {
                        // down
                        nextIndex = currentIndex < max ? currentIndex + 1 : max
                    }
                    this.removeIndex()
                    this.resetIndex(nextIndex)
                    this.dropdownItem[nextIndex].focus()
                    event.preventDefault()
                    event.stopPropagation()
                } else if (keyCode === 13) {
                    //enter选中
                    event.target.click()
                }
                return;
            },
            removeIndex() {
                this.dropdownItem.forEach(ele => {
                    ele.setAttribute("tabindex", "-1")
                })
            },
            resetIndex(index) {
                this.dropdownItem[index].setAttribute("tabindex", "0")
            },
            hide() {
                this.removeIndex();
                clearTimeout(this.timeout);
                this.timeout = setTimeout(() => {
                    this.visible = false;
                }, this.trigger === 'click' ? 0 : 150);
            },
            show() {
                clearTimeout(this.timeout);
                this.timeout = setTimeout(() => {
                    this.visible = true;
                }, this.trigger === 'click' ? 0 : 150);
            },
            handleMenuItemClick(command) {
                this.hide()
                this.$emit("command", command)
            }
        },

        watch: {
            visible(val) {
                //console.log(`即将为${val ? "显示" : "隐藏"}状态`)
                this.broadcast(this.$children, "mjDropdownMenu", "visible", [val])
            }
        },
        render(h) {
            return ( <div class="my-dropdown"> {this.$slots.default} {this.$slots.dropdown} </div>)
        }
    }
</script>

<style>
    .my-dropdown {
        display: inline-block;
        position: relative;
    }
</style>
